package ch15
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    
    import utils.Tree;
    
    /**
     * Trees加强版；
     * 可用上下左右键控制方向，空格键向上飞起.
     */
    [SWF(backgroundColor=0x000000)]
    public class Trees2 extends Sprite
    {
        private var trees:Array;
        private var numTrees:uint = 100;
        private var fl:Number = 250;
        //消失点
        private var vpX:Number = stage.stageWidth / 2;
        private var vpY:Number = stage.stageHeight / 2;
        //地板
        private var floor:Number = 50;
        private var ax:Number = 0;
        private var ay:Number = 0;
        private var az:Number = 0;
        private var vx:Number = 0;
        private var vy:Number = 0;
        private var vz:Number = 0;
        //重力
        private var gravity:Number = 0.3;
        //摩擦力
        private var friction:Number = 0.98;
        
        public function Trees2()
        {
            init();
        }
        
        private function init():void
        {
            trees = new Array();
            for (var i:uint = 0; i < numTrees; i++)
            {
                var tree:Tree = new Tree();
                trees.push(tree);
                tree.xpos = Math.random() * 2000 - 1000;
                tree.ypos = floor;
                tree.zpos = Math.random() * 10000;
                addChild(tree);
            }
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
        }
        
        private function onEnterFrame(event:Event):void
        {
            vx += ax;
            vy += ay;
            vz += az;
            vy -= gravity;
            for (var i:uint = 0; i < numTrees; i++)
            {
                var tree:Tree = trees[i];
                move(tree);
            }
            vx *= friction;
            vy *= friction;
            vz *= friction;
            sortZ();
        }
        
        private function onKeyDown(event:KeyboardEvent):void
        {
            switch (event.keyCode)
            {
                case Keyboard.UP:
                    az = -1;
                    break;
                case Keyboard.DOWN:
                    az = 1;
                    break;
                case Keyboard.LEFT:
                    ax = 1;
                    break;
                case Keyboard.RIGHT:
                    ax = -1;
                    break;
                case Keyboard.SPACE:
                    ay = 1;
                    break;
                default:
                    break;
            }
        }
        
        private function onKeyUp(event:KeyboardEvent):void
        {
            switch (event.keyCode)
            {
                case Keyboard.UP:
                case Keyboard.DOWN:
                    az = 0;
                    break;
                case Keyboard.LEFT:
                case Keyboard.RIGHT:
                    ax = 0;
                    break;
                case Keyboard.SPACE:
                    ay = 0;
                    break;
                default:
                    break;
            }
        }
        
        private function move(tree:Tree):void
        {
            tree.xpos += vx;
            tree.ypos += vy;
            tree.zpos += vz;
            if (tree.ypos < floor)
            {
                tree.ypos = floor;
            }
            //公式:scale = fl / (fl + z)
            /**
             * 当物体离屏幕很近时，即物体在观察点后面时候，将物体拉远；
             * 当物体距离太远时，将物体拉近。
             * */
            if (tree.zpos < -fl)
            {
                tree.zpos += 10000;
            }
            if (tree.zpos > 10000 - fl)
            {
                tree.zpos -= 10000;
            }
            var scale:Number = fl / (fl + tree.zpos);
            tree.scaleX = tree.scaleY = scale;
            tree.x = vpX + tree.xpos * scale;
            tree.y = vpY + tree.ypos * scale;
			trace(tree.y,tree.ypos,scale,tree.ypos * scale);
            tree.alpha = scale;
        }
        
        private function sortZ():void
        {
            //按降序、数字排序
            trees.sortOn("zpos", Array.DESCENDING | Array.NUMERIC);
            for each (var tree:Tree in trees)
            {
                addChild(tree);
            }
        }
    }
}